<?php
/**
 * Created by PhpStorm.
 * User: zhanglihe
 * Date: 17/11/2
 * Time: 下午2:33
 */

namespace App\Service;

use App\Model\UserBank;
use App\Service\baofu\Entity\AccInfoEntity as AccInfo;
use App\Service\baofu\Entity\ContentBodyEntity as ContentBody;
use App\Service\baofu\Entity\HeaderEntity as Header;
use App\Service\baofu\Entity\OpenAccountEntity as OpenAccount;
use App\Service\baofu\Entity\PostMasterEntity;
use App\Service\baofu\Entity\PostParmEntity as PostParm;
use App\Service\baofu\Entity\PublicPostEntity as PublicPost;
use App\Service\baofu\SecurityUtil\JuheSignatureUtils;
use App\Service\baofu\Entity\TransAccountEntity as TransAccount;
use App\Service\baofu\SecurityUtil\NewRsaUtil;
use App\Service\baofu\Util\HttpClient;
use App\Service\baofu\Util\Log;
use App\Service\baofu\Util\Tools;
use App\Service\baofu\Entity\ValuesActionEntity as ValuesAction;
use App\Service\baofu\Entity\ValuesAcctInfoEntity as ValuesAcctInfo;
use App\Service\baofu\Entity\SyncUploadFileEntity as SyncUploadFile;
use App\Service\baofu\Entity\FileNameEntity as FileName;
use App\Service\baofu\Entity\PostFilesParmsEntity as PostFilesParms;
use Carbon\Carbon;

class BaofuPay
{
    private $merId = '1285874';
    private $terId = '92786';

    private $merId1 = '1285873';
    private $terId1 = '92785';
    private $version = "1.0.0";
    private $keyPwd = "568239";
    private $postUrl = 'https://juhe.baofoo.com/api';
    private $tpApiUrl = "https://public.baofu.com/union-gw/api/";
    public $pfxFilePath;
    public $cerFilePath;
    public $bfFilePath;

    public function __construct()
    {
//        $this->pfxFilePath = base_path('app/service/baofu/CerFile/siyao.pfx');
//        $this->cerFilePath = base_path('app/service/baofu/CerFile/gongyao.cer');
//        $this->bfFilePath = base_path('app/service/baofu/CerFile/baofu.cer');

        $this->cerFilePath = app_path('Service/baofu/CerFile/gongyao.cer');
        $this->pfxFilePath = app_path('Service/baofu/CerFile/siyao.pfx');
        $this->bfFilePath = app_path('Service/baofu/CerFile/baofu.cer');
    }

    /**
     * 开户操作
     */
    public function openAccount($data)
    {
        $serviceTp = "BCT3-1002-001-01";
        $accType = 1;
        $mobileNo = $data['tel_no'];
        $cardNo = $data['card_id'];
        $customerName = $data['card_name'];
        $certificateNo = $data['cert_id'];

        $bodyInfo = new OpenAccount();
        $bodyInfo->accType = $accType;
        $bodyInfo->version = $this->version;
        $bodyInfo->businessType = "BCT3";
        $bodyInfo->noticeUrl = "https://ylz.yimitongxun.com/api/account/notify";
        $accInfo = $this->createAccInfo($customerName, $certificateNo, $cardNo, $mobileNo,$data['user_id']);
        $bodyInfo->accInfo = $accInfo;

        return $this->sendRequest($serviceTp, $bodyInfo);
    }

    public function openAgent($data)
    {
        $serviceTp = "BCT3-1002-001-01";
        $accType = 1;
        $mobileNo = $data['tel_no'];
        $cardNo = $data['card_id'];
        $customerName = $data['card_name'];
        $certificateNo = $data['cert_id'];

        $bodyInfo = new OpenAccount();
        $bodyInfo->accType = $accType;
        $bodyInfo->version = $this->version;
        $bodyInfo->businessType = "BCT3";
        $bodyInfo->noticeUrl = "https://ylz.yimitongxun.com/api/agent/notify";
        $accInfo = $this->createAgent($customerName, $certificateNo, $cardNo, $mobileNo,$data['agent_id']);
        $bodyInfo->accInfo = $accInfo;

        return $this->sendRequest($serviceTp, $bodyInfo);
    }

    public function updateAccountEnterprises($data){
        $serviceTp = "BCT3-1005-001-01";
        $accType = 2;
        $optType = 2;
        $bodyInfo = new OpenAccount();
        $bodyInfo->accType = $accType;
        $bodyInfo->version = $this->version;
        $bodyInfo->businessType = "BCT3";
        $bodyInfo->optType = $optType;
        $bodyInfo->noticeUrl = "https://ylz.yimitongxun.com/api/account/notify";
        $accInfo = $this->updateAccInfoEnterprise($data);
        $bodyInfo->accInfo = $accInfo;
        return $this->sendRequest($serviceTp, $bodyInfo);
    }

    /**
     * 开户操作
     */
    public function openAccountEnterprises($data)
    {
        $serviceTp = "BCT3-1002-001-01";
        $accType = 2;
        $cardNo = $data['card_id'];
        $customerName = $data['card_name'];
        $certificateNo = $data['cert_id'];
        //企业需要邮箱
        $email = $data['email'];
        $enterpriseInfo = $data;//企业的相关信息

        $bodyInfo = new OpenAccount();
        $bodyInfo->accType = $accType;
        $bodyInfo->version = $this->version;
        $bodyInfo->businessType = "BCT3";
        $bodyInfo->noticeUrl = "https://ylz.yimitongxun.com/api/account/notify";
        $accInfo = $this->createAccInfoEnterprise($data);
        $bodyInfo->accInfo = $accInfo;

        return $this->sendRequest($serviceTp, $bodyInfo);
    }

    /**
     * 开户结果查询
     */
    public function getAccountInfo()
    {
        $serviceTp = "BCT3-1003-001-01";
        $accType = 1;
        $userLn = "LN17469610105350";

        $queryBody = new PublicPost();
        $queryBody->version = $this->version;
        $queryBody->accType = $accType;
        $queryBody->loginNo = $userLn;

        return $this->sendRequest($serviceTp, $queryBody);
    }

    /**
     * 换卡操作
     */
    public function changeCard($data,$contractNo)
    {
        $serviceTp = "BCT3-1005-001-01";
        $newCardNo = $data['card_id'];;
        $accType = 1;
        $mobileNo = $data['tel_no'];

        $accInfo = new AccInfo();
        $accInfo->contractNo = $contractNo;
        $accInfo->cardNo = $newCardNo;
        $accInfo->transSerialNo = Tools::getTsnOderid("TSN");
        $accInfo->mobileNo = $mobileNo;

        $modBody = new PublicPost();
        $modBody->version = $this->version;
        $modBody->accType = $accType;
        $modBody->optType = "02";
        $modBody->accInfo = $accInfo;
        return $this->sendRequest($serviceTp, $modBody);
    }

    /**
     * 获取绑卡信息
     */
    public function getBindCardInfo($loginNo,$type=1)
    {
        $serviceTp = "BCT3-1008-001-01";
        $userLn = $loginNo;

        $queryBody = new PublicPost();
        $queryBody->version = $this->version;
        $queryBody->accType = $type;
        $queryBody->loginNo = $userLn;

        return $this->sendRequest($serviceTp, $queryBody);
    }

    /**二级户之间转账
     * @param $payerNo
     * @param $payeeNo
     * @param $amount
     * @return mixed|null
     * @throws \Exception
     */
    public function transferMember($payerNo,$amount,$payeeNo='CP660000000130527558'){
        $serviceTp = "BCT3-3001-001-01";
        $transSerialNo = Tools::getTsnOderid("TSN");
        $tracce = new TransAccount();
        $tracce->version = "1.0.0";
        $tracce->transSerialNo = $transSerialNo;
        $tracce->payerNo = $payerNo;
        $tracce->payeeNo = $payeeNo;
        $tracce->dealAmount = $amount;
        $tracce->accountType= 'BALANCE';
        return $this->sendRequest($serviceTp, $tracce);
    }


    /**账户余额查询
     * @param $contractNo
     * @param $accType
     * @return mixed|null
     * @throws \Exception
     */
    public function queryAmount($contractNo='CP660000000130527558',$accType = 1){
        $serviceTp = "BCT3-2001-001-01";
        $tracce = new TransAccount();
        $tracce->version = "1.0.0";
        $tracce->accType = $accType;
        $tracce->contractNo = $contractNo;
        return $this->sendRequest($serviceTp, $tracce);
    }

    /*
     * @Desc:转账（提现）
     */
    public function transferCash($amount,$user,$orderNo){
        $serviceTp = "BCT3-3002-001-01";
        $transSerialNo = $orderNo;
        $tracce = new TransAccount();
        $tracce->version = "1.0.0";
        $tracce->contractNo = $user->account_id;
        $tracce->transSerialNo = $transSerialNo;
        $tracce->dealAmount = $amount;
        $tracce->returnUrl = "https://ylz.yimitongxun.com/api/account/notify";
        $tracce->feeMemberId = $user->account_id;
        return $this->sendRequest($serviceTp, $tracce);
    }

    public function transferCashAgent($amount,$user,$orderNo){
        $serviceTp = "BCT3-3002-001-01";
        $transSerialNo = $orderNo;
        $tracce = new TransAccount();
        $tracce->version = "1.0.0";
        $tracce->contractNo = $user->account_id;
        $tracce->transSerialNo = $transSerialNo;
        $tracce->dealAmount = $amount;
        $tracce->returnUrl = "https://ylz.yimitongxun.com/api/agent/notify";
        $tracce->feeMemberId = $user->account_id;
        return $this->sendRequest($serviceTp, $tracce);
    }

    /*
     * 分账接口
     * 账户加值
     */
    public function subAccount($amount,$user){
        $serviceTp = "BCT3-5001-001-01";
        $reqTime = Tools::getTime("YmdHis");

        $transOrderNo = Tools::getTsnOderid("TON");
        $orderNo = Tools::getTsnOderid("ORG");//商户原支付交易订单的订单号,（目前不与原单校验）
        $accountType = "BALANCE";

        $listvaie = [];
        $vaie1 = new ValuesAcctInfo();
        $vaie1->contractNo = $user->account_id;
        $vaie1->transAmount = $amount;

        $listvaie[] = $vaie1;

        $vsae = new ValuesAction();
        $vsae->version = $this->version;
        $vsae->transSerialNo = $transOrderNo;
        $vsae->reqTime = $reqTime;
        $vsae->platformNo = $this->merId;
        $vsae->accountType = $accountType;
        $vsae->transOrderNo = $transOrderNo;
        $vsae->orderNo = $orderNo;
        $vsae->acctInfo = $listvaie;
        $vsae->dealAmountAct();//统计总金额。
        return $this->sendRequest($serviceTp, $vsae);
    }

    /*
    * 分账接口
    * 账户减值
    */
    public function desAccount($amount,$user){
        $serviceTp = "BCT3-5002-001-01";
        $reqTime = Tools::getTime("YmdHis");

        $transOrderNo = Tools::getTsnOderid("TON");
        $orderNo = Tools::getTsnOderid("ORG");//商户原支付交易订单的订单号,（目前不与原单校验）
        $accountType = "BALANCE";

        $listvaie = [];
        $vaie1 = new ValuesAcctInfo();
        $vaie1->contractNo = $user->account_id;
        $vaie1->transAmount = $amount;

        $listvaie[] = $vaie1;

        $vsae = new ValuesAction();
        $vsae->version = $this->version;
        $vsae->transSerialNo = $transOrderNo;
        $vsae->reqTime = $reqTime;
        $vsae->platformNo = $this->merId;
        $vsae->accountType = $accountType;
        $vsae->transOrderNo = $transOrderNo;
        $vsae->orderNo = $orderNo;
        $vsae->acctInfo = $listvaie;
        $vsae->dealAmountAct();//统计总金额。
        return $this->sendRequest($serviceTp, $vsae);
    }
    /*
     * 上传资质接口
     *  二级商户类型	附件名	类型ID
        公司	企业营业执照	101
        公司	开户许可证(或开户凭证)	102
        公司	法人身份证正面	104
        公司	法人身份证反面	111
        公司	与平台合作协议	401
        公司	特殊行业许可证(酒店/旅馆)	999
        个体工商户	个体工商户营业执照	101
        个体工商户	开户许可证/经营者本人银行卡正面照	102
        个体工商户	经营者身份证正面	104
        个体工商户	经营者身份证反面	111
        个体工商户	与平台合作协议	401
        个体工商户	特殊行业许可证(酒店/旅馆)	999
        自然人	个人身份证正面	301
        自然人	个人身份证反面	302
        自然人	本人名下状态正常银行卡	311
        自然人	与平台合作协议	401
        自然人	特殊行业资格证书	999
     */
    public function syncUploadFile($filePath){
        try {
            $OrderType = "0";
//            $filezip = "G:\\pict\\idphoto.zip";
            $filezip = $filePath;

            $suf = new SyncUploadFile();
            $suf->accType="2";
            $suf->transSerialNo = Tools::getTsnOderid("TSN");
            $suf->businessParams = "";

            $file101 = new FileName();
            $file101->fileName = "business_license";
            $file101->fileType = "101";

//            $file102 = new FileName();
//            $file102->fileName = "acc_open_license";
//            $file102->fileType = "102";

            $file104 = new FileName();
            $file104->fileName = "id_front";
            $file104->fileType = "104";

            $file111 = new FileName();
            $file111->fileName = "id_reverse";
            $file111->fileType = "111";

            $suf->AddFileNameMap($file101);
            $suf->AddFileNameMap($file104);
            $suf->AddFileNameMap($file111);

            $pfp = new PostFilesParms();
            //$pfp->file = curl_file_create(realpath($filezip),mime_content_type($filezip),basename($filezip));

//            Log::EchoFormat(realpath($filezip).",".mime_content_type($filezip).",".basename($filezip));
            $sufJson = json_encode($suf);
//            Log::EchoFormat("JSON".$sufJson);

            $pfp->memberId =$this->merId;
            $pfp->terminalId = $this->terId;
            $pfp->orderType = $OrderType;
            $pfp->content = NewRsaUtil::encryptByPfx($sufJson,$this->pfxFilePath,$this->keyPwd);
            $returnstr = \App\baocaitong3\Util\HttpClient::MultiPost($pfp,"https://upload.baofoo.com/baofu-upload-trade/trade/syncUploadFile",$filezip);
//            Log::EchoFormat($returnstr);
            if(empty($returnstr)) throw new \Exception("请求返回为空！");
            \Illuminate\Support\Facades\Log::info('return_str'.json_encode($returnstr));
            $debyresult = NewRsaUtil::decrptByPub($returnstr,$this->bfFilePath);
            \Illuminate\Support\Facades\Log::info("解密：".$debyresult);
            $resultObj = json_decode($debyresult,true);
            if($resultObj["success"])
            {
                \Illuminate\Support\Facades\Log::info("流水号：".$resultObj["result"]["transSerialNo"]);
                foreach ($resultObj["result"]["dfsFileNotifyList"] as $item)
                {
                    \Illuminate\Support\Facades\Log::info("文件：".json_encode($item));
                }
            }
            return $resultObj;
        }catch (\Exception $ex){
            \Illuminate\Support\Facades\Log::info($ex->getMessage());
        }
    }

    /*
     *
     */

    /**
     * 创建账户信息对象
     * @param string $customerName 客户名称
     * @param string $certificateNo 证件号
     * @param string $cardNo 卡号
     * @param string $mobileNo 手机号
     * @return AccInfo
     */
    private function createAccInfo($customerName, $certificateNo, $cardNo, $mobileNo,$user_id)
    {
        $accInfo = new AccInfo();
        $accInfo->transSerialNo = Tools::getTsnOderid("TSN");
        $accInfo->loginNo = md5($user_id.$certificateNo);
        $accInfo->customerName = $customerName;
        $accInfo->certificateNo = $certificateNo;
        $accInfo->cardNo = $cardNo;
        $accInfo->needUploadFile = false;
        $accInfo->certificateType = "ID";
        $accInfo->mobileNo = $mobileNo;
        $accInfo->cardUserName = $customerName;

        if ($accInfo->needUploadFile) {
            $accInfo->qualificationTransSerialNo = "";
        }

        return $accInfo;
    }

    private function createAgent($customerName, $certificateNo, $cardNo, $mobileNo,$user_id)
    {
        $accInfo = new AccInfo();
        $accInfo->transSerialNo = Tools::getTsnOderid("TSN");
        $accInfo->loginNo = md5('A'.$user_id.$certificateNo);
        $accInfo->customerName = $customerName;
        $accInfo->certificateNo = $certificateNo;
        $accInfo->cardNo = $cardNo;
        $accInfo->needUploadFile = false;
        $accInfo->certificateType = "ID";
        $accInfo->mobileNo = $mobileNo;
        $accInfo->cardUserName = $customerName;

        if ($accInfo->needUploadFile) {
            $accInfo->qualificationTransSerialNo = "";
        }
        return $accInfo;
    }

    /**
     * 创建账户信息企业
     * @param string $customerName 客户名称
     * @param string $certificateNo 证件号
     * @param string $cardNo 卡号
     * @param string $mobileNo 手机号
     * $param array $enterpriseInfo 企业信息
     * @return AccInfo
     */
    private function createAccInfoEnterprise($data)
    {
        $accInfo = new AccInfo();
        $accInfo->transSerialNo = Tools::getTsnOderid("TSN");
        $userBank = UserBank::where('id',$data['id'])->first();
        $userBank->order_no = $accInfo->loginNo = md5($data['user_id'].$data['cert_id']);
        $userBank->save();
        $accInfo->email = $data['email'];
        $accInfo->selfEmployed = $data['bus_type']?true:false;
        $accInfo->customerName = $data['name'];
        $accInfo->certificateNo = $data['social_credit_code'];
        $accInfo->certificateType = "LICENSE";
        $accInfo->corporateName = $data['legal_person'];
        $accInfo->corporateCertType = 'ID';
        $accInfo->corporateCertId = $data['cert_id'];
        $accInfo->corporateMobile = $data['legal_mp'];
        $accInfo->industryId = $data['industry'];
        $accInfo->cardNo = $data['card_id'];
        $accInfo->bankName = $data['bank_name'];
        $accInfo->needUploadFile = true;
        $accInfo->depositBankProvince = $data['province'];
        $accInfo->depositBankCity = $data['city'];
        $accInfo->depositBankName = $data['bank_detail'];
        //企业不同的
         //是否个体户 企业为false，不传默认为false
        if($accInfo->selfEmployed){
            $accInfo->cardUserName = $data['legal_person'];
        }
        if ($accInfo->needUploadFile) {
            $accInfo->qualificationTransSerialNo = $data['attach_file'];
        }
        \Illuminate\Support\Facades\Log::info('acc-info'.json_encode($accInfo));
        return $accInfo;
    }

    private function updateAccInfoEnterprise($data){
        $accInfo = new AccInfo();
        $accInfo->transSerialNo = Tools::getTsnOderid("TSN");
        $accInfo->contractNo = $data['account_id'];
        $accInfo->cardNo = $data['card_id'];
        $accInfo->bankName = $data['bank_name'];
        $accInfo->depositBankProvince = $data['province'];
        $accInfo->depositBankCity = $data['city'];
        $accInfo->depositBankName = $data['bank_detail'];
        $accInfo->corporateMobile = $data['legal_mp'];
        if($data['bus_type']){
            $accInfo->contactName = $data['card_name'];
            $accInfo->contactMobile = $data['legal_mp'];
        }
        \Illuminate\Support\Facades\Log::info('edit-acc-info'.json_encode($accInfo));
        return $accInfo;
    }

    private function uploadZip($path){
        $serviceTp = "BCT3-3002-001-01";
        $type = 0;
    }


    /**
     * 生成请求头
     * @param string $serviceTp 服务类型
     * @return Header
     */
    private function getHeader($serviceTp)
    {
        $headerInfo = new Header();
        $headerInfo->memberId = $this->merId;
        $headerInfo->terminalId = $this->terId;
        $headerInfo->serviceTp = $serviceTp;
        $headerInfo->verifyType = "1";
        return $headerInfo;
    }

    /**
     * 发送请求
     * @param string $serviceTp 服务类型
     * @param mixed $body 请求体
     * @throws \Exception
     */
    private function sendRequest($serviceTp, $body)
    {
        $headerInfo = $this->getHeader($serviceTp);

        $contBody = new ContentBody();
        $contBody->header = $headerInfo;
        $contBody->body = $body;

        $contentStr = json_encode($contBody);
        Log::EchoFormat("JSON序列号：" . $contentStr);

        $enContent = NewRsaUtil::encryptByPfx($contentStr, $this->pfxFilePath, $this->keyPwd);

        $postParm = new PostParm();
        $postParm->memberId = $this->merId;
        $postParm->terminalId = $this->terId;
        $postParm->content = $enContent;

        $resultPost = HttpClient::Post($postParm, $this->tpApiUrl . $serviceTp . "/transReq.do");
        Log::EchoFormat("返回参数：" . $resultPost);

        if (empty($resultPost)) {
            throw new \Exception("请求返回异常");
        }

        if (strpos($resultPost, "header") !== false) {
            $resulterror = json_decode($resultPost, true);
        } else {
            $dePostString = NewRsaUtil::decrptByPub($resultPost, $this->bfFilePath);
            Log::EchoFormat("解密返回：" . $dePostString);

            if (empty($dePostString)) {
                throw new \Exception("解密空值，请检查证书是否正常");
            }

            if (strpos($dePostString, "header") !== false) {
                $contenBe = json_decode($dePostString, true);
                if ($contenBe["header"]["sysRespCode"] === "S_0000") {
                    Log::EchoFormat("业务层结果:" . json_encode($contenBe["header"]));
                    if ($contenBe["body"]["retCode"] === 1) {
                        Log::EchoFormat("结果:" . json_encode($contenBe["body"]));
                    }
                }
            }
            return  $contenBe["body"];
        }
    }


}
